package cn.buk.tms.eotms.dao;


import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.common.sc.Page;
import cn.buk.tms.eotms.entity.*;
import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;


import java.util.*;


/**
 * @author yfdai
 */
@Repository
@Component
@Transactional
public class UserDaoImpl extends AbstractDao implements UserDao {

  @Override
  public User getUserByUsername(String username) {
    List<User> list = em.createQuery("select u from User u where u.username = ?1", User.class)
        .setParameter(1, username).getResultList();

    return list.size() == 0 ? null : list.get(0);
  }

  @Override
  public User getUserById(int id) {
    return em.find(User.class, id);
  }

  @Override
  public List<RolePrivilege> searchPrivileges(int enterpriseId, int userId) {
    return em.createQuery("select o from RolePrivilege o " +
        "where o.enterpriseId = :enterpriseId " +
        "and o.role in (" +
        "   select distinct o.role from GroupRole o where o.groupInfo in (" +
        "       select o1 from Groups o1 where o1.id in (select o2.groupInfo.id from GroupUsers o2 where o2.userInfo.id = :userId)" +
        ")" +
        ")", RolePrivilege.class)
        .setParameter("enterpriseId", enterpriseId)
        .setParameter("userId", userId)
        .getResultList();
  }

  @Override
  public List<AmountHistory> searchTransHistory(final int ownerId, final int enterpriseId, CommonSearchCriteria sc) {
    List<AmountHistory> results = null;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<AmountHistory> cq = cb.createQuery(AmountHistory.class);
    Root<AmountHistory> root = cq.from(AmountHistory.class);
    root.alias("o");

    List<Predicate> predicates = new ArrayList<>();
    Predicate predicate = cb.conjunction();
    predicates.add(predicate);

    predicate = cb.equal(root.get(AmountHistory_.ownerId), ownerId);
    predicates.add(predicate);

    predicate = cb.equal(root.get(AmountHistory_.enterpriseId), enterpriseId);
    predicates.add(predicate);


//    if (sc.getStatus() > 0) {
//      predicate = cb.equal(root.get(AmountHistory_.orderType), sc.getStatus());
//      predicates.add(predicate);
//    }
//
//    if (sc.getType() == 0) {
//      //现金账户
//      predicate = cb.notEqual(root.get(AmountHistory_.orderType), 10);
//      predicates.add(predicate);
//    } else if (sc.getType() == 1) {
//      //积分账户
//      predicate = cb.equal(root.get(AmountHistory_.orderType), 10);
//      predicates.add(predicate);
//    }
//
//    if (sc.getRemark() != null && sc.getRemark().trim().length() > 0) {
//      predicate = cb.like(root.get(AmountHistory_.remark), "%" + sc.getRemark().trim() + "%");
//      predicates.add(predicate);
//    }


    //计算根据条件查询得出的数据总数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<AmountHistory> countRoot = countQuery.from(AmountHistory.class);
    countRoot.alias("o");

    countQuery.select(cb.count(countRoot)).where(predicates.toArray(new Predicate[predicates.size()]));
    Long count = em.createQuery(countQuery).getSingleResult();

    int maxResults = count.intValue();
    if (maxResults > 0) {
      cq.where(predicates.toArray(new Predicate[predicates.size()]));

      List<Order> orderByes = new ArrayList<>();
      orderByes.add(cb.desc(root.get("id")));
      cq.orderBy(orderByes);

      Page page = sc.getPage();
      page.setRowCount(maxResults);
      int i = (page.getPageNo() - 1) * page.getPageSize();

      results = em.createQuery(cq)
              .setFirstResult(i)
              .setMaxResults(page.getPageSize()).getResultList();

    }
    if (results == null) {
      results = new ArrayList<>();
    }

    return results;
  }

  @Override
  public int createUserBindWeixin(UserBindWeixin o) {
    em.persist(o);
    return o.getId();
  }

  @Override
  public UserBindWeixin getUserByOpenid(int ownerId, String openid) {
    List<UserBindWeixin> lists = em.createQuery("select o from UserBindWeixin o where o.ownerId = :ownerId and o.weixinOpenId = :openid", UserBindWeixin.class)
            .setParameter("ownerId", ownerId)
            .setParameter("openid", openid)
            .getResultList();

    return lists.size() > 0 ? lists.get(0) : null;
  }

}
